package com.gomokult.dao.impl;

import com.gomokult.dao.CommentDAO;
import com.gomokult.entity.Comment;
import com.gomokult.exception.InvalidIDException;
import com.gomokult.exception.NoSuchPageException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import static com.gomokult.utility.JDBCUtil.*;

/**
 * 文件：CommentDAOimpl.java
 * 作者：赵哲群
 * 完成度：已完成
 * 最后修改日期：2023-7-3
 */
public class CommentDAOImpl implements CommentDAO {
	private CommentDAOImpl() {}
	private static final CommentDAOImpl singleton = new CommentDAOImpl();
	public static CommentDAOImpl getSingleton() { return singleton; }

    @Override
    public Comment selectComment(int commentID) throws InvalidIDException {
        try {
            String sql = "select * from gamecomments where commentID = ?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1, commentID);
            ResultSet rs = pstat.executeQuery();
            Comment comment;
            if(rs.next()){
                if(rs.getInt("parentComment")==0)
                    comment = new Comment(rs.getInt("commentID"),rs.getInt("game"),UserDAOImpl.getSingleton().selectUserbyID(rs.getInt("publisher")) ,null,
                         rs.getTimestamp("date"),rs.getString("content"),rs.getInt("ReferencedRounds"));
                else
                    comment = new Comment(rs.getInt("commentID"),rs.getInt("game"),UserDAOImpl.getSingleton().selectUserbyID(rs.getInt("publisher")) ,CommentDAOImpl.getSingleton().selectComment(rs.getInt("parentComment")),
                             rs.getTimestamp("date"),rs.getString("content"),rs.getInt("ReferencedRounds"));
                return comment;
            }else{
                return null;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int selectCommentsCount(int gameID) throws InvalidIDException {
        try {
            String sql = "select commentCount from historygames where gameID = ?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1, gameID);
            ResultSet rs = pstat.executeQuery();
            if(rs.next()){
                int CommentsCount = rs.getInt("commentCount");
                return CommentsCount;
            }else{
                throw new InvalidIDException();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int selectCommentPagesCount(int gameID) throws InvalidIDException {
        try {
            String sql = "select commentCount from historygames where gameID = ?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1, gameID);
            ResultSet rs = pstat.executeQuery();
            if(rs.next()){
                int CommentsCount = rs.getInt("commentCount");
                return (int) Math.ceil(CommentsCount/20.0);
            }else{
                throw new InvalidIDException();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<Comment> selectCommentsFromPage(int gameID, int page) throws InvalidIDException, NoSuchPageException {
        int haspage = selectCommentPagesCount(gameID);
        List <Comment> list = new ArrayList<Comment>();
        if(haspage<page)
            throw new NoSuchPageException();
        try {
            String sql = "select * from gamecomments where game = ? order by date DESC limit 20 offset ?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1, gameID);
            pstat.setInt(2, (page - 1) * 20);
            ResultSet rs = pstat.executeQuery();
            while(rs.next()){
                Comment comment = new Comment(rs.getInt("commentID"),rs.getInt("game"),UserDAOImpl.getSingleton().selectUserbyID(rs.getInt("publisher")) ,
                        CommentDAOImpl.getSingleton().selectComment(rs.getInt("parentComment")), rs.getTimestamp("date"),rs.getString("content"),rs.getInt("ReferencedRounds"));
                list.add(comment);
            }
            if(list.isEmpty())
                throw new InvalidIDException();
            else
                return list;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteComment(int commentID) throws InvalidIDException {
        try{
            String sql = "delete from gamecomments where commentID = ?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1,commentID);
            int result = pstat.executeUpdate();
            if(result==0)
                throw new InvalidIDException();
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
    }

    @Override
    public void clearComment(int gameID) throws InvalidIDException {
        try{
            String sql = "delete from gamecomments where game = ?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1,gameID);
            int result = pstat.executeUpdate();
            if(result==0)
                throw new InvalidIDException();
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
    }

    @Override
    public void insertComment(Comment comment) {
        try{
            String sql = "insert into gamecomments(game,publisher,parentComment,date,content,ReferencedRounds) values(?,?,?,?,?,?)";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1,comment.getGame());
            pstat.setInt(2,comment.getPublisher().getUserID());
            if(comment.getParentComment()==null)
                pstat.setNull(3,java.sql.Types.INTEGER);
            else
                pstat.setInt(3,comment.getParentComment().getCommentID());

            pstat.setTimestamp(4, comment.getDate());
            pstat.setString(5,comment.getContent());
            pstat.setInt(6,comment.getReferencedRound());
            pstat.executeUpdate();
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
    }

    @Override
    public int selectCommentId(int userID, int gameID, Timestamp date) {
        try{
            String sql = "select * from gamecomments where publisher=? and game=? and date=?";
            pstat = con.prepareStatement(sql);
            pstat.setInt(1,userID);
            pstat.setInt(2,gameID);
            pstat.setTimestamp(3,date);
            rs = pstat.executeQuery();
            rs.next();
            int a= rs.getInt("commentID");
            return a;

        }catch (SQLException e){
            throw new RuntimeException(e);
        }
    }


}
